package com.supermarket.framework.aspectj;


import com.supermarket.common.annotation.AutoFill;
import com.supermarket.common.enums.OperationType;
import com.supermarket.common.utils.DateUtils;
import com.supermarket.common.utils.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Date;

@Aspect
@Component
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AutoFillAspect {
    /**
     * 定义切入点
     */
    @Pointcut("@annotation(com.supermarket.common.annotation.AutoFill)")
    public void autoFillPointCut() {}

    @Before("autoFillPointCut()")
    public void autoFill(JoinPoint joinPoint) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
        OperationType value = autoFill.value();

        Object[] args = joinPoint.getArgs();
        if(args == null || args.length == 0) {
            return;
        }

        Object entity = args[0];

        if(value == OperationType.INSERT) {
            Method setCreateId = entity.getClass().getDeclaredMethod("setCreateId", Long.class);
            Method setCreateBy = entity.getClass().getDeclaredMethod("setCreateBy", String.class);
            Method setCreateTime = entity.getClass().getDeclaredMethod("setCreateTime", Date.class);

            Method setUpdateId = entity.getClass().getDeclaredMethod("setUpdateId", Long.class);
            Method setUpdateBy = entity.getClass().getDeclaredMethod("setUpdateBy", String.class);
            Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", Date.class);



            setCreateId.invoke(entity, SecurityUtils.getUserId());
            setCreateBy.invoke(entity, SecurityUtils.getLoginUser().getUser().getNickName());
            setCreateTime.invoke(entity, DateUtils.getNowDate());

            setUpdateId.invoke(entity,SecurityUtils.getUserId());
            setUpdateBy.invoke(entity,SecurityUtils.getLoginUser().getUser().getNickName());
            setUpdateTime.invoke(entity, DateUtils.getNowDate());

        }else if(value == OperationType.UPDATE) {
            Method setUpdateId = entity.getClass().getDeclaredMethod("setUpdateId", Long.class);
            Method setUpdateBy = entity.getClass().getDeclaredMethod("setUpdateBy", String.class);
            Method setUpdateTime = entity.getClass().getDeclaredMethod("setUpdateTime", Date.class);

            setUpdateId.invoke(entity,SecurityUtils.getUserId());
            setUpdateBy.invoke(entity,SecurityUtils.getLoginUser().getUser().getNickName());
            setUpdateTime.invoke(entity, DateUtils.getNowDate());
        }
    }

}
